// 异步编程
// js中按代码顺序依次执行叫同步编程，等待上一步代码执行完毕后再执行后续代码
// 当某一步代码执行花费时间长，按同步编程，此后与该步代码无关的代码需等待非必要时间
// 异步编程，将执行时间长的代码及相关代码进行封装，在代码执行时，可以先执行后续无关代码，减少等待时间


// setTimeout()
setTimeout(console.log,1000,"1");
// 原始异步策略，选用setTimeout函数，等待若干时间后，再将执行代码推到执行队列，实现异步操作
// 第一个参数为函数本省，第二个参数为等待函数执行时间，单位为ms，第三个参数为函数传入的参数
// 缺点：当若干个异步行为进行嵌套时，需采用若干个setTimeout进行函数嵌套


// 期约
// 期约是对一个待定值的描述，通过执行函数对期约进行初始化，实现对一个待定值的描述，利用期约的方法，实现对待定值的异步行为
// 1.创建期约
let p=new Promise((resolve,reject)=>{setTimeout(reject,1000,"3")});
// 期约是一个引用类型,可以通过new Promise进行实例化
// 其构造函数传入参数为一个执行函数，用于初始化期约
// 执行函数可选参数为reject和resolve，分别代表期约的落定状态
// 在执行函数中，调用resolve或reject会终止执行函数，并返回相关拒绝理由或是解决值
// 执行函数以及期约定义为同步编程
let p1=Promise.reject("a");
let p2=Promise.resolve("a");
// 一个立即落定的期约可以通过Promise.reject和Promise.resolve进行创建，传入参数分别为拒绝理由和解决值
// 在Promise.resolve中传入一个期约，其返回值为该传入期约，会保留期约的状态，具有幂等性
// 在Promise.reject中传入一个期约，返回的是以该期约为拒绝理由的拒绝期约

// 2.期约特性
// 期约是对一个待定值的描述
// 期约具有待定，解决，拒绝三种状态
// 期约可以由待定状态落定为解决或者拒绝状态，为单向不可逆过程
// 期约在解决状态时，具有解决值，在拒绝状态时，具有拒绝理由
// 在期约落定为拒绝状态时，会抛出一个仅有期约相关方法进行捕获的错误

// 3.期约实例方法
// (1)thenable接口
// 定义的对象具有then方法，则该对象具有期约的特性
let pro={
    then(){},
}

// (2)then()方法
p.then((x)=>{console.log("resolve:"+x);return x},(x)=>{console.log("reject:"+x);return x});
// 第一个参数为期约落定为解决时执行的函数，第二个参数为期约落定为拒绝时执行的函数
// 传入的参数为函数本身，可以显示利用匿名函数包装执行代码
// 当期约落定后，会按落定的状态执行不同的函数
// 其落定的解决值或拒绝理由会传入参数函数中，实现参数传递
// then方法会将参数函数中的返回值利用Promise.resolve进行包装，作为一个解决期约，其解决值为参数函数的返回值
// 在参数函数中抛出错误（throw），其错误会被Promise.resolve进行包装
p.then(null,(x)=>{console.log(x)});
// 仅含期约落定拒绝时的参数函数

// (3)catch()方法
p.catch((x)=>{console.log(x)});
// 其与p.then(null,reject)一致

// (4)finally()方法
p.finally((x)=>{console.log("finally:"+x);return x});
// 当期约落定后会执行参数函数，并将落定值传入函数
// 返回值大多数为父期约的传递
// 当返回值为待定期约时，会返回待定期约
// 当参数函数显示抛出错误(throw)或返回一个拒绝期约时，返回值为一个拒绝期约


// 4.期约特性
// 期约非重入性：即在调用期约落定方法时，在期约落定后才将参数函数推入到执行队列
// 此前由执行代码时，会等待上述代码执行完成后，才执行参数函数
// 代码执行时会先执行同步操作(包括期约的定义程序)，等待期约落定后才执行期约落定方法，此时才会将参数函数推入执行队列 
// 在同一个期约的落定方法的参数函数按照添加顺序依次执行
// 非同一个期约的落定方法的参数函数按期约落定顺序添加进执行队列


// 5.期约连锁与合成
// 期约传递，调用期约的方法，其返回值也为期约，实现了若干个异步操作的串联
// 期约落定，相关异步操作，返回值为一个期约，以此循环实现串联
// 期约值的传递，期约落定后，调用相关方法，其期约值会传入参数函数的参数，在参数函数中返回参数，对其值进行期约包装，实现期约值的传递
// 期约的有向非循环图，利用期约的then方法，在期约落定后会执行不同的解决和拒绝的处理程序，再返回一个期约，实现了类似二叉树结构

Promise.race([p1,p2,p,4]);
// 传入参数为一个期约数组，对于非期约值会用Promise.resolve进行包装
// 返回值为最先落定的一个期约，但是会等待所有期约都尽可能落定后才执行返回操作

Promise.all([p1,p2,p,4]);
// 传入参数为一个期约数组，对于非期约值会用Promise.resolve进行包装
// 当期约数组全落定为解决期约时，返回值为一个解决期约，其解决值为所有解决值的数组
// 当期约数组中存在待定期约和拒绝期约时，返回值为第一个拒绝或待定期约
// 当所有期约都尽可能落定后，才会执行返回操作

